<?php
/**
 * Created by PhpStorm.
 * User: longli
 * Date: 2020/04/14
 * Time: 11:34
 * @link http://www.lmterp.cn
 */

namespace app\common\model;

use Exception;
use think\Collection;
use think\exception\DbException;
use think\Model;
use think\model\relation\HasMany;

/**
 * 订单模型
 * Class Order
 * @package app\common\model
 */
class Orders extends BaseModel
{
    protected $pk = 'order_id';

    protected $autoWriteTimestamp = 'datetime';

    // 设置 json 字段
    protected $json = ['ext_json'];

    protected $insert = ['create_by', 'update_by'];

    protected $update = ['update_by'];

    /**
     * 未标记
     * @var int
     */
    const FLAG_SENT_NO = 0;

    /**
     * 已标记
     * @var int
     */
    const FLAG_SENT_YES = 1;

    /**
     * 不需要标记
     * @var int
     */
    const FLAG_SENT_NO_NEED = 2;

    /**
     * 部分标记
     * @var int
     */
    const FLAG_SENT_PART = 3;

    public static $ORDER_FLAG = [
        self::FLAG_SENT_NO      => '未标记',
        self::FLAG_SENT_YES     => '已标记',
        self::FLAG_SENT_NO_NEED => '不需要标记',
        self::FLAG_SENT_PART    => '部分标记',
    ];

    /**
     * 待处理
     */
    const ORDER_WAIT = 0;

    /**
     * 申报中
     */
    const ORDER_DECLARE_ING = 1;

    /**
     * 异常
     */
    const ORDER_EXCEPTION = 5;

    /**
     * 捡货中
     */
    const ORDER_PACKAGE = 20;

    /**
     * 待出货
     */
    const ORDER_WAIT_OUT = 25;

    /**
     * 已发货
     */
    const ORDER_SEND = 30;

    /**
     * 已退款
     */
    const ORDER_RETURN = 35;

    /**
     * 部分退款
     */
    const ORDER_RETURN_PART = 36;

    /**
     * 已拒付
     */
    const ORDER_REJECT = 40;

    /**
     * 风险
     */
    const ORDER_RISK = 45;

    /**
     * 刷单
     */
    const ORDER_FALSE = 50;

    /**
     * 取消订单
     */
    const ORDER_CANCEL = 55;

    /**
     * 缺货
     */
    const ORDER_LACK = 60;

    /**
     * 价格低
     */
    const ORDER_PRICE_LOW = 65;

    /**
     * 订单完成
     */
    const ORDER_SUCCESS = 70;

    public static $ORDER_STATUS = [
        self::ORDER_WAIT        => '待处理',
        self::ORDER_DECLARE_ING => '申报中',
        self::ORDER_EXCEPTION   => '异常',
        self::ORDER_PACKAGE     => '捡货中',
        self::ORDER_WAIT_OUT    => '待出货',
        self::ORDER_SEND        => '已发货',
        self::ORDER_RETURN      => '已退款',
        self::ORDER_RETURN_PART => '部分退款',
        self::ORDER_REJECT      => '已拒付',
        self::ORDER_RISK        => '风险',
        self::ORDER_FALSE       => '刷单',
        self::ORDER_CANCEL      => '取消订单',
        self::ORDER_LACK        => '缺货',
        self::ORDER_PRICE_LOW   => '价格低',
        self::ORDER_SUCCESS     => '订单完成',
    ];

    /**
     * 未发货
     */
    const SEND_WAIT = 0;

    /**
     * 更换渠道
     */
    const SEND_UPDATE = 5;

    /**
     * 部分发货
     */
    const SEND_PART = 20;

    /**
     * 已发货
     */
    const SEND_ALL = 25;

    /**
     * 超时未发货
     */
    const SEND_WAIT_TIMEOUT = 30;

    /**
     * 全部退货
     */
    const SEND_RETURN_ALL = 40;

    /**
     * 部分退货
     */
    const SEND_RETURN_PART = 45;

    /**
     * 不需要发货
     */
    const SEND_NO_NEED = 50;

    public static $SEND_STATUS = [
        self::SEND_WAIT         => '未发货',
        self::SEND_UPDATE       => '更换渠道',
        self::SEND_PART         => '部分发货',
        self::SEND_ALL          => '已发货',
        self::SEND_WAIT_TIMEOUT => '超时未发货',
        self::SEND_RETURN_ALL   => '全部退货',
        self::SEND_RETURN_PART  => '部分退货',
        self::SEND_NO_NEED      => '不需要发货',
    ];

    /**
     * 未标记
     */
    const FLAG_N = 0;

    /**
     * 已标记
     */
    const FLAG_Y = 1;

    /**
     * 不需要标记
     */
    const FLAG_NN = 2;

    /**
     * 部分标记
     */
    const FLAG_S = 3;

    public static $FLAG_STATUS = [
        self::FLAG_N   => '未标记',
        self::FLAG_Y   => '已标记',
        self::FLAG_NN  => '不需要标记',
        self::FLAG_S   => '部分标记',
    ];


    /**
     * 已打印
     */
    const PRINT_Y = 1;

    /**
     * 未打印
     */
    const PRINT_N = 0;

    public static $PRINT_STATUS = [
        self::PRINT_N => '未打印',
        self::PRINT_Y => '已打印',
    ];

    protected function getIsPrintAttr($value)
    {
        return isset(self::$PRINT_STATUS[$value])
            ? self::$PRINT_STATUS[$value]
            : $value;
    }

    protected function setIsPrintAttr($value)
    {
        $temp = array_flip(self::$PRINT_STATUS);
        return isset($temp[$value])
            ? $temp[$value]
            : $value;
    }

    protected function getOrderStatusAttr($value)
    {
        return isset(self::$ORDER_STATUS[$value])
            ? self::$ORDER_STATUS[$value]
            : $value;
    }

    protected function setOrderStatusAttr($value)
    {
        $temp = array_flip(self::$ORDER_STATUS);
        return isset($temp[$value])
            ? $temp[$value]
            : $value;
    }

    protected function setSendStatusAttr($value)
    {
        $temp = array_flip(self::$SEND_STATUS);
        return isset($temp[$value])
            ? $temp[$value]
            : $value;
    }

    protected function getSendStatusAttr($value)
    {
        return isset(self::$SEND_STATUS[$value])
            ? self::$SEND_STATUS[$value]
            : $value;
    }

    protected function getIsFlagSentAttr($value)
    {
        return isset(self::$FLAG_STATUS[$value])
            ? self::$FLAG_STATUS[$value]
            : $value;
    }

    protected function setIsFlagSentAttr($value)
    {
        $temp = array_flip(self::$FLAG_STATUS);
        return isset($temp[$value])
            ? $temp[$value]
            : $value;
    }

    protected function setCreateByAttr()
    {
        if($this->isCli) return 0;
        $admin = session('lmterp');
        return $admin ? $admin->id : 0;
    }

    protected function setUpdateByAttr()
    {
        if($this->isCli) return 0;
        $admin = session('lmterp');
        return $admin ? $admin->id : 0;
    }

    /**
     * 一对多关联订单详情
     * @return HasMany
     * @date 2020/04/14
     * @author longli
     */
    public function detail()
    {
        return $this->hasMany(OrdersDetail::class, 'order_id', 'order_id');
    }

    public function track()
    {
        return $this->hasOne(ChannelOrders::class, 'order_id', 'order_id')->where("is_cancel", "=", ChannelOrders::CANCEL_N);
    }

    public function admin()
    {
        return $this->belongsTo(Admin::class, "create_by", "id");
    }

    public function currcode()
    {
        return $this->belongsTo(Countries::class, 'currency', 'currency_code');
    }

    /**
     * 多对一订单关联账号
     * @date 2020/08/26
     * @author longli
     */
    public function account()
    {
        return $this->belongsTo(Account::class);
    }

    /**
     * 通过 id 获取订单
     * @param int|int[] $ids 单个或多个订单
     * @return array|Collection
     * @date 2020/04/14
     * @author longli
     */
    public static function getListById($ids)
    {
        if(!is_array($ids)) $ids = [$ids];
        $orders = [];
        try
        {
            $orders = static::whereIn('order_id', $ids)->select();
        }
        catch(DbException $exception){}
        return count($ids) == 1 && !empty($orders) ? $orders[0] : $orders;
    }

    /**
     * 通过内部订单号获取订单
     * @param string|array $orderSn
     * @return array|Model|null
     * @date 2020/04/16
     * @author longli
     */
    public static function getByNo($orderSn)
    {
        if(!is_array($orderSn)) $orderSn = [$orderSn];
        $orders = [];
        try
        {
            $orders =  static::whereIn("order_sn", $orderSn)->select();
        }catch(DbException $e){}
        return count($orderSn) == 1 && !empty($orders) ? $orders[0] : $orders;
    }

    /**
     * 通过平台订单号获取订单
     * @param string|array $orderNo 平台订单号
     * @param string $platform 平台
     * @return array|string|Collection
     * @date 2020/04/16
     * @author longli
     */
    public static function getBySn($orderNo, $platform = '')
    {
        if(!is_array($orderNo)) $orderNo = [$orderNo];
        $where = ["order_no" =>  $orderNo];
        if(!empty($platform)) $where['order_source'] = $platform;
        $orders = [];
        try
        {
            $orders = static::where($where)->select();
        }catch(DbException $e){}
        return count($orderNo) == 1 && !empty($orders) ? $orders[0] : $orders;
    }

    /**
     * 获取买家名称
     * @param Orders|int $orders 订单订单id
     * @return string
     * @date 2020/09/04
     * @author longli
     */
    public static function getBuyerName($orders)
    {
        if(is_numeric($orders)) $orders = static::get($orders);
        return $orders->consignee ? : ($orders->buyer_first_name . ' ' . $orders->buyer_last_name);
    }

    /**
     * 通过订单id批量修改数据
     * @param int|int[] $ids 订单id
     * @param array $data 值
     * @return bool
     * @date 2020/09/03
     * @author longli
     */
    public static function editByOrderId($ids, $data)
    {
        try
        {
            foreach(static::where("order_id", "in", $ids)->select() as $order)
            {
                if(isset($data['is_print']) && $data['is_print'] == self::PRINT_Y && $order->order_status == self::$ORDER_STATUS[self::ORDER_WAIT])
                    $data['order_status'] = self::ORDER_PACKAGE;
                if(!empty($data['logistics_name']) && !empty($data['channel_id']))
                {
                    $data['label_url'] = '';
                    $data['is_print'] = self::PRINT_N;
                    if($order->send_status != self::SEND_WAIT) $data['send_status'] = self::SEND_UPDATE;
                    $data['shipping_code'] = '';
                    $data['logistics_price'] = 0;
                }
                $order->save($data);
            }
            return true;
        }catch(Exception $e)
        {
            return false;
        }
    }
}